home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / MacGS 2.5.2ß3 / (MacGSLib.π) / PAP.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-17  |  8.0 KB  |  398 lines  |  [TEXT/R*ch]

  1. /*
  2.    Routines to interface to PAP driver.  See MacTutor, Sep '86; also Jan '88.
  3.    This routines are meant to replace the assembly language "glue" given in
  4.    the Sep '86 article.  Refer to the article for info on how to use these
  5.    routines.
  6.  
  7.    Original code by Sak Wathanasin (sw%kernel.co.uk or ....!mcvax!ukc!kernel!sw)
  8.    Adapted 06MAR93 for MacGS by Martin Fong (mwfong@nisc.sri.com)
  9.  
  10.    This file (or a project built from it) can be included in any project that
  11.    wants to talk to the PAP routines.
  12.  
  13. Synopsis:
  14.  
  15.    typedef struct
  16.    {
  17.            long  systemStuff;
  18.         char  statusStr[256];
  19.  
  20.    } PAPStatusRec, *PAPStatusPtr;
  21.   
  22.    pascal short PAPOpen (refNum, printerName, flowQuantum, statusBuf, compState)
  23.     short           *refNum;
  24.     char           *printerName;
  25.     short            flowQuantum;
  26.     PAPStatusPtr    statusBuf;
  27.  
  28.    pascal short PAPRead (refNum, buffer, length, eof, compState)
  29.     short            refNum;
  30.     char           *buffer;
  31.     short           *length;
  32.     short           *eol;
  33.     short           *compState;
  34.  
  35.    pascal short PAPWrite (refNum, buffer, length, eof, compState)
  36.     short            refNum;
  37.     char           *buffer;
  38.     short            length;
  39.     short            eol;
  40.     short           *compState;
  41.  
  42.    pascal short PAPClose (refNum)
  43.     short            refNum;
  44.  
  45.     typedef struct AddrBlock
  46.     {
  47.         short        aNet;
  48.         Byte        aNode;
  49.         Byte        aSocket;
  50.  
  51.     } AddrBlock;
  52.  
  53.    pascal short PAPStatus (printerName, statusBuff, netAddr)
  54.     char           *printerName;
  55.     PAPStatusPtr    statusBuff;
  56.     AddrBlock       *netAddr;
  57.  
  58.    OSErr PAPLoad   (StringPtr *pLWName, StringPtr *pLWType, StringPtr *pLWZone)
  59.  
  60.    OSErr PAPUnload (void)
  61.  
  62. */
  63.  
  64.  
  65. #include "PAP.h"
  66. #include <Folders.h>
  67.  
  68.  
  69. #define    NIL                    0L
  70.  
  71.  
  72. extern Boolean        gHasFindFolder;        //    System 7 FindFolder present
  73.  
  74.  
  75. static Handle        hPAP = (Handle) NIL;
  76. static Ptr            papPtr;                 /* points to locked PAP mgr */
  77. static StringHandle    hLWName;            /* handle to locked entity name */
  78. static StringPtr    lwNameP;
  79. static StringPtr    lwTypeP;
  80. static StringPtr    lwZoneP;
  81. static StringHandle    hDriverFName;        /* handle to printer driver name */
  82.  
  83.  
  84. static OSErr    GetPAPDriver (Handle *pDriverCode,
  85.                               StringHandle *pDriverFName, StringHandle *pLWName);
  86.  
  87.  
  88.     OSErr
  89. PAPLoad (StringPtr *pLWName, StringPtr *pLWType, StringPtr *pLWZone)
  90.  
  91. {
  92.     OSErr    status = noErr;
  93.  
  94.  
  95.     if (hPAP == (Handle) NIL)
  96.     {
  97.         if ((status = GetPAPDriver (&hPAP, &hDriverFName, &hLWName)) == noErr)
  98.         {
  99.             papPtr    = *hPAP;
  100.  
  101.             lwNameP = *hLWName;
  102.             lwTypeP = lwNameP + (short) lwNameP[0] + 1;
  103.             lwZoneP = lwTypeP + (short) lwTypeP[0] + 1;
  104.         }
  105.     }
  106.  
  107.     if (status == noErr)
  108.     {
  109.         *pLWName = lwNameP;
  110.         *pLWType = lwTypeP;
  111.         *pLWZone = lwZoneP;
  112.     }
  113.  
  114.     return status;
  115. }
  116.  
  117.  
  118.     pascal short
  119. PAPOpen (short *refNum, char *printerName, short flowQuantum, PAPStatusPtr statusBuf)
  120.  
  121. {
  122.     asm
  123.     {
  124.         move.l  papPtr, A0
  125.         jmp        0(A0)
  126.     }
  127. }
  128.  
  129.  
  130.     pascal short
  131. PAPRead (short refNum, char *buffer, short *length, short *eol, short *compState)
  132.  
  133. {
  134.     asm
  135.     {
  136.         move.l  papPtr, A0
  137.         jmp        4(A0)
  138.     }
  139. }
  140.  
  141.  
  142.     pascal short
  143. PAPWrite (short refNum, char *buffer, short length, short eol, short *compState)
  144.  
  145. {
  146.     asm
  147.     {
  148.         move.l  papPtr, A0
  149.         jmp        8(A0)
  150.     }
  151. }
  152.  
  153.  
  154.     pascal short
  155. PAPStatus (char *printerName, PAPStatusPtr statusBuff, AddrBlock *netAddr)
  156.  
  157. {
  158.     asm
  159.     {
  160.         move.l  papPtr, A0
  161.         jmp        12(A0)
  162.     }
  163. }
  164.  
  165.  
  166.     pascal short
  167. PAPClose (short refNum)
  168.  
  169. {
  170.     asm
  171.     {
  172.         move.l  papPtr, A0
  173.         jmp        16(A0)
  174.     }
  175. }
  176.  
  177.  
  178. /* The PAP driver installs several VBL tasks that must be removed
  179.    using the PAP unload call before disposing of the PAP code
  180. */
  181.  
  182.     OSErr
  183. PAPUnload (void)
  184.  
  185. {
  186.     OSErr   status = noErr;
  187.  
  188.  
  189.     if (hPAP /* != (Handle) NIL */)
  190.     {
  191.         asm
  192.         {
  193.             subq.l  #2, sp
  194.             move.l  papPtr, A0
  195.             jsr        20(A0)
  196.             move.w  (sp)+, status      /* save the result from the PAP call */
  197.         }
  198.  
  199.         /* Can PAPUnload ever return an error?  We assume not... */
  200.  
  201.         DisposHandle ((Handle) hLWName);        /* junk the LW name                */
  202.         DisposHandle ((Handle) hPAP);            /* junk the PAP driver            */
  203.         DisposHandle ((Handle) hDriverFName);    /* junk the printer driver name    */
  204.  
  205.         hPAP = (Handle) NIL;
  206.     }
  207.  
  208.     return status;
  209. }
  210.  
  211.  
  212. /*
  213.  *    OSErr GetPAPDriver (Handle *pDriverCode, StringHandle *pLWName)
  214.  *
  215.  *    returns noErr if able to locate a LaserWriter driver, else an OS error.
  216.  *    In the former case, the locked PAP driver code and printer name are
  217.  *    also returned.  In the latter case, GetPAPDriver () may also return the
  218.  *    following:
  219.  *
  220.  *        noPrinterChosenErr        no printer was selected in the Chooser
  221.  *        printerNotFoundErr        printer file not found
  222.  *        notPAPPrinterErr        printer does not support PAP
  223.  *
  224.  *    Adapted from DTS' October 1992 "Print Access Protocol Q&As" in the
  225.  *    "New Technical Notes".
  226.  *
  227.  */
  228.  
  229.     static OSErr
  230. GetPAPDriver (Handle *pDriverCode, StringHandle *pDriverFName, StringHandle *pLWName)
  231.  
  232. {
  233.     Str255            driverFName;
  234.     short            theResFile;
  235.     StringHandle    hDriverFName;
  236.     OSErr            status = noErr;
  237.  
  238.  
  239.     /*...Obtain the Chooser printer driver filename from the system...*/
  240.  
  241.     if ((hDriverFName = ChooserPrinterName ()) == (StringHandle) NIL)
  242.     {
  243.         status = noPrinterChosenErr;
  244.         goto premature_exit;
  245.     }
  246.  
  247.     /*...Open the printer driver file...*/
  248.  
  249.     if ((theResFile = OpenPrinterFile (hDriverFName)) == -1)
  250.     {
  251.         status = printerNotFoundErr;
  252.         DisposHandle ((Handle) hDriverFName);
  253.  
  254.         goto premature_exit;
  255.     }
  256.  
  257.     if ((status = ResError ()) == noErr)
  258.     {
  259.         Handle            hDriverCode;
  260.         StringHandle    LWNameH;
  261.  
  262.  
  263.         /*...Get the printer driver code...*/
  264.  
  265.         if ((hDriverCode = GetResource ('PDEF', 10)) == (Handle) NULL)
  266.         {
  267.             status = notPAPPrinterErr;
  268.             DisposHandle ((Handle) hDriverFName);
  269.  
  270.             goto premature_exit;
  271.         }
  272.  
  273.         /*...Relocate the driver code to the top of the application heap
  274.          *     and lock it.
  275.          */
  276.  
  277.         DetachResource (hDriverCode);
  278.         MoveHHi (hDriverCode);
  279.         HLock (hDriverCode);
  280.         HNoPurge (hDriverCode);
  281.  
  282.         /*...Now get the printer entity name from the printer driver...*/
  283.  
  284.         if ((LWNameH = (StringHandle) GetResource ('PAPA', -8192))
  285.                 == (StringHandle) NULL)
  286.         {
  287.             status = ResError ();
  288.             DisposHandle ((Handle) hDriverFName);
  289.             DisposHandle (hDriverCode);
  290.  
  291.             goto premature_exit;
  292.         }
  293.  
  294.         /*...Relocate the printer entity name to the top of the application heap
  295.          *     and lock it.
  296.          */
  297.  
  298.         DetachResource ((Handle) LWNameH);
  299.         MoveHHi ((Handle) LWNameH);
  300.         HLock ((Handle) LWNameH);
  301.         CloseResFile (theResFile);
  302.  
  303.         /*...Return the locked code driver and printer entity name...*/
  304.  
  305.         *pDriverCode  = hDriverCode;
  306.         *pDriverFName = hDriverFName;
  307.         *pLWName      = LWNameH;
  308.     }
  309.  
  310. premature_exit:
  311.  
  312.     return status;
  313. }
  314.  
  315.  
  316. /*
  317.  *    StringHandle ChooserPrinterName (void)
  318.  *
  319.  *    Returns Chooser-selected printer name or (StringHandle) NULL if
  320.  *    there is no current printer selection.  It is the responsibility
  321.  *    of the caller to dispose of the returned handle.
  322.  *
  323.  */
  324.  
  325.     StringHandle
  326. ChooserPrinterName (void)
  327.  
  328. {
  329.     StringHandle    hDriverFName = (StringHandle) GetResource ('STR ', -8192);
  330.  
  331.  
  332.     if (hDriverFName /* != (StringHandle) NULL */)
  333.         DetachResource ((Handle) hDriverFName);
  334.  
  335.     return hDriverFName;
  336. }
  337.  
  338.  
  339. /*
  340.  *    short OpenPrinterFile (StringHandle hDriverFName)
  341.  *
  342.  *    Given a handle to the name of the current Chooser printer, returns a reference
  343.  *    number to the corresponding printer driver file, or -1 if it can't be opened.
  344.  *
  345.  */
  346.  
  347.     short
  348. OpenPrinterFile (StringHandle hDriverFName)
  349.  
  350. {
  351.     short    sysVRefNum;
  352.     long    sysDirID    = 0L;
  353.     OSErr    status        = noErr;
  354.     short    theResFile    = -1;
  355.  
  356.  
  357.     /*...The 7.x Way!...*/
  358.  
  359.     if (gHasFindFolder)
  360.     {
  361.         status = FindFolder (kOnSystemDisk, kExtensionFolderType,
  362.                              kDontCreateFolder, &sysVRefNum, &sysDirID);
  363.     }
  364.  
  365.     /*...If FindFolder was not available, use good ol' SysEnvirons (thanks Jim)...*/
  366.  
  367.     else
  368.     {
  369.          SysEnvRec    theWorld;
  370.  
  371.  
  372.         if ((status = SysEnvirons (1, &theWorld)) == noErr)
  373.             sysVRefNum = theWorld.sysVRefNum;
  374.     }
  375.  
  376.     /*...Okay, at this point we should have found the folder where the drivers
  377.      *     are.  If we are running under System 7.x, this folder will be the
  378.      *     extensions folder in the System folder.  If we are pre-7.x, this will
  379.      *     be the System folder.  If FindFolder was available, then we have to
  380.      *     use HOpenResFile because FindFolder requires dirIDs.  If we used
  381.      *     SysEnvirons (i.e., pre-7.x), then we need to use OpenRFPerm.
  382.      */
  383.  
  384.     if (status == noErr)
  385.     {
  386.         HLock ((Handle) hDriverFName);
  387.  
  388.         if (gHasFindFolder)
  389.             theResFile = HOpenResFile (sysVRefNum, sysDirID, *hDriverFName, fsRdPerm);
  390.         else
  391.             theResFile = OpenRFPerm (*hDriverFName, sysVRefNum, fsRdPerm);
  392.  
  393.         HUnlock ((Handle) hDriverFName);
  394.     }
  395.  
  396.     return theResFile;
  397. }
  398.